package cn.edu.nju.ws.sview.database;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * ������ݿ��¼����
 * @author Gong Saisai
 *
 */
public class DBUpdater {
    private static DBUpdater INSTANCE = null;
    private boolean stopped ;
    private Object lock;
    //��Ӧ��
    private ArrayList<Object> objects = null;
    //��Ӧ��ķ���
    private ArrayList<Method> methods= null;
    //��Ӧ�����Ĳ���
    private ArrayList<Object[]> arguments = null;
    private DBUpdater(){
    	this.lock = new Object();
    	this.stopped = false;
    	this.objects = new ArrayList<Object>();
    	this.methods = new ArrayList<Method>();
    	this.arguments = new ArrayList<Object[]>();
    	new TaskThread().start();
    }
    
    /**
     * �ύ��ݿ�ĸ�������
     * ���objects�������ݲ���ɾ��֮�����ӣ�����ÿ������������ΨһID
     * @return
     */
    public int submitTask(Object object, String methodName, Class<?>[] argumentTypes,Object[] m_arguments){
    	int taskId=0;
    	Method method = null;
    	try {
			method = object.getClass().getMethod(methodName, argumentTypes) ;
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	synchronized(this.lock){
    		taskId = this.objects.size();
    		objects.add(object) ;
    		methods.add(method);
    		arguments.add(m_arguments) ;
    	}
    	return taskId;
    }
    
    /**
     * �ж��ض������Ƿ����
     * @return
     */
    public boolean isCompleted(int taskId){
    	synchronized(this.lock){
    		return (this.objects.get(taskId)==null);
    	}
    }
    
    /**
     * ��ֹ��ݿ��̨�����߳�
     */
    public void exit(){
    	synchronized(lock){
    		this.objects.add(null);
    		this.methods.add(null);
    		this.arguments.add(null) ;
    	}
    	
    	while(!this.stopped){
    		try {
				Thread.sleep(10) ;
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    }
    
    public static DBUpdater getInstance(){
    	if(INSTANCE==null){
    		INSTANCE = new DBUpdater();
    	}
    	return INSTANCE;
    }
    
    private class TaskThread extends Thread{
    	public void run(){
    		int taskId = 0;
    		while(true){
    			boolean sleep =true;
    			synchronized(DBUpdater.this.lock){
    				if(taskId<DBUpdater.this.objects.size())
    					sleep =false;
    			}
    			if(sleep){
    				try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					continue;
    			}
    			Object object = null;
    			Method method = null;
    			Object[] arguments = null;
    			synchronized(DBUpdater.this.lock){
    				object = DBUpdater.this.objects.get(taskId) ;
    				method = DBUpdater.this.methods.get(taskId);
    				arguments =DBUpdater.this.arguments.get(taskId);
    			}
				if(object==null){
					break;
				}
				try {
					method.invoke(object, arguments) ;
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				synchronized(DBUpdater.this.lock){
					DBUpdater.this.objects.set(taskId, null) ;
					DBUpdater.this.methods.set(taskId, null) ;
					DBUpdater.this.arguments.set(taskId, null) ;
				}
				taskId++;
    		}
    		DBUpdater.this.stopped = true;
    	}
    }
}
